import java.util.ArrayList;

public class TesteThread {

	@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		Control c = new Control();
		ArrayList<Agent> A = new ArrayList<Agent>();
		for (int i = 0; i<10000; i++) {
			A.add(new Agent(i));
		}
		
		ArrayList<Runner> R = new ArrayList<Runner>();
		for (int n=1; n <=50; n++) {
			R.add(new Runner(A, c));
		}
		for (Runner r : R) {
			r.start();
		}
		
		for (int it = 1; it <= 10; it++) {
			long begin=System.currentTimeMillis();
			System.out.print("Iteration " + it + "... ");
			c.a = -1;
			
			for (Runner r : R) {
				r.runAgain();
			}
			
			boolean running = true;
			do {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				running = false;
				for (Runner r : R) {
					if (r.ok) {
						running = true;
						break;
					}
				}
			} while (running);
			System.out.println("done in "+(System.currentTimeMillis()-begin)+"ms");
		}
		for (Runner r : R) {
			r.stop();
		}
		
	}
	
	public static class Runner extends Thread {
		ArrayList<Agent> A;
		Control c;
		boolean ok;
		
		public Runner(ArrayList<Agent> A, Control c) {
			this.A = A;
			this.c = c;
			this.ok = false;
		}
		public void runAgain() {
			this.ok = true;	
		}
		public Agent getAgent() {
			synchronized (c) {
				c.a++;
				if (c.a >= A.size()) return null;
				return A.get(c.a);
			}
		}
		@Override
		public void run() {
			while (true) {
				//System.out.println(getName() + ": I'm running");
				if (ok) {
					Agent a = getAgent();
					while (a != null) {
						
						a.step();
						System.out.println(getName()+": agent " + a.id + " has been run");
						
						try {
							sleep(1);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						a = getAgent();
					}
					
					ok = false;
				}
				try {
					sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
		}
	}
	
	public static class Agent {
		int id;
		int count = 0;
		public Agent(int id) {
			this.id=id;
		}
		public void step() {
			count++;
			//System.out.println("Agent "+id+": '"+count+"'");
		}
	}
	
	public static class Control {
		int a = -1;
	}

}
